/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.*/

package com.nhc.model;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;

import com.astrob.NavFrameSDK;
import com.astrob.model.LonLat;
import com.astrob.naviframe.Start;
import com.astrob.nhcmap.R;
import com.astrob.view.MapViewS;

import org.mapsforge.core.graphics.Style;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.core.util.MercatorProjection;
import org.mapsforge.map.android.graphics.AndroidGraphicFactory;
import org.mapsforge.map.model.DisplayModel;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.util.BoundingBox;
import org.osmdroid.views.MapView;
import org.osmdroid.views.Projection;

import zuo.biao.library.base.BaseModel;

public class MapSetInfo extends BaseModel {

    private static final long serialVersionUID = 1L;

    //地图设置
    private static String MAPSETINFO = "mapset";

    private static String MAPSET_MODE = "mapset_mode";//地图方向模式
    private static String MAPSET_USEWG = "mapset_usewg";//使用地图网格
    private static String MAPSET_WGDISTANCES = "mapset_wgdistances";//网格距离

    private static String MAPSET_CARICONTYPE = "mapset_caricontype";//车标类型
    private static String MAPSET_GCJ02 = "mapset_gcj02";//

    public static String[] MODEDIR_NAMES = {"上为北", "上为航向"};

    private int mapdirmode = 0;//地图方向模式 0-上为北 1-上为航向
    private boolean usewg = false;//使用地图网格
    private double wgdistance = 1000;//网格距离 米
    private int caricontype = 0;
    private boolean isgcj02 = false;//当前加载的离线栅格图是否为火星坐标

    private static MapSetInfo instance = new MapSetInfo();

    public static MapSetInfo getInstance() {
        return instance;
    }

    /**
     * 默认构造方法，JSON等解析时必须要有
     */
    public MapSetInfo() {
        //default
    }

    public void save(Context context) {
        if (context == null) {
            return;
        }

        SharedPreferences sp = context.getSharedPreferences(
                MAPSETINFO, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt(MAPSET_MODE, this.mapdirmode);
        editor.putBoolean(MAPSET_USEWG, this.usewg);
        editor.putString(MAPSET_WGDISTANCES, this.wgdistance + "");
        editor.putInt(MAPSET_CARICONTYPE, this.caricontype);
        editor.putBoolean(MAPSET_GCJ02, this.isgcj02);
        editor.commit();
    }

    public void load(Context context) {
        if (context == null) {
            return;
        }
        MODEDIR_NAMES = context.getResources().getStringArray(R.array.mapsetinfo_modedir_names);

        SharedPreferences sp = context.getSharedPreferences(
                MAPSETINFO, Context.MODE_PRIVATE);
        this.mapdirmode = sp.getInt(MAPSET_MODE, this.mapdirmode);
        this.usewg = sp.getBoolean(MAPSET_USEWG, this.usewg);
        this.wgdistance = Double.valueOf(sp.getString(MAPSET_WGDISTANCES, this.wgdistance + ""));
        this.caricontype = sp.getInt(MAPSET_CARICONTYPE, this.caricontype);
        this.isgcj02 = sp.getBoolean(MAPSET_GCJ02, this.isgcj02);

    }

    public void reset() {
        mapdirmode = 0;
        usewg = false;
        wgdistance = 30;
        caricontype = 0;
        isgcj02 = false;
    }

    public String getMapdirmodeStr() {
        if (mapdirmode < 0 || mapdirmode >= MODEDIR_NAMES.length) {
            mapdirmode = 0;
        }
        return MODEDIR_NAMES[mapdirmode];
    }

    public int getMapdirmode() {
        return mapdirmode;
    }

    public void setMapdirmode(int mapdirmode) {
        this.mapdirmode = mapdirmode;
    }

    public boolean isUsewg() {
        return usewg;
    }

    public void setUsewg(boolean usewg) {
        this.usewg = usewg;
    }

    public boolean isgcj02() {
        return isgcj02;
    }

    public void setIsgcj02(boolean isgcj02) {
        this.isgcj02 = isgcj02;
    }

    public double getWgdistance() {
        return wgdistance;
    }

    public void setWgdistance(double wgdistance) {
        this.wgdistance = wgdistance;
    }

    public int getCaricontype() {
        return caricontype;
    }

    public void setCaricontype(int caricontype) {
        this.caricontype = caricontype;
    }

    @Override
    protected boolean isCorrect() {//根据自己的需求决定，也可以直接 return true
        return id > 0;// && StringUtil.isNotEmpty(phone, true);
    }

    public void draw(Context context, Canvas canvas, float ws, MapViewS mapView) {
        if (!usewg) {
            return;
        }

        if (mapView == null) {
            return;
        }
        double[] regions = mapView.getMapRegion();
        double _maxLon, _maxLat, _minLon, _minLat;
        _maxLon = regions[0];
        _maxLat = regions[1];
        _minLon = regions[2];
        _minLat = regions[3];

        NavFrameSDK.CllDegreePreMeter llDegree = Start.getInstance().MapKit().GetUnitDegree();
        double xLon = llDegree.londegree * wgdistance;//x 轴 单位刻度 0～180
        double xLat = llDegree.latdegree * wgdistance;//y 轴 单位刻度 0～90

        int iX = (int) (_minLon / xLon);
        int eX = (int) (_maxLon / xLon) + 1;
        double x0 = iX * xLon;//网格x0
        double x1 = (iX + 1) * xLon;//网格x1

        int iY = (int) (_minLat / xLat);
        int eY = (int) (_maxLat / xLat) + 1;
        double y0 = iY * xLat;//网格y0
        double y1 = (iY + 1) * xLat;//网格y1

        Point posX0 = Start.getInstance().MapKit().LL2XY(new LonLat(x0, y0));//y0不重要
        Point posX1 = Start.getInstance().MapKit().LL2XY(new LonLat(x1, y0));

        Point posY0 = Start.getInstance().MapKit().LL2XY(new LonLat(x0, y0));//x0不重要
        Point posY1 = Start.getInstance().MapKit().LL2XY(new LonLat(x0, y1));

        int DX = posX1.x - posX0.x;
        int DY = posY0.y - posY1.y;

        if (DX * ws < 30 || DY * ws < 30) {
            return;
        }
//test
//        double dd = Start.getInstance().MapKit().getDistance(new LonLat(x0, y0), new LonLat(x1, y0));

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(2);
        paint.setColor(Color.parseColor("#AAAAAAAA"));
        paint.setAntiAlias(true);

        float startX = 0;
        float startY = 0;
        float stopX = 0;
        float stopY = mapView.getHeight();

        for (int i = 0; i < (eX - iX); i++) {
            if (i == 0) {
                startX = posX0.x * ws;
            } else {
                startX += DX * ws;
            }
            canvas.drawLine(startX, startY, startX, stopY, paint);
        }

        startX = mapView.getWidth();
        for (int i = 0; i < (eY - iY); i++) {
            if (i == 0) {
                startY = posY1.y * ws;
            } else {
                startY -= DY * ws;
            }
            canvas.drawLine(0, startY, startX, startY, paint);
        }

    }

    //test
//        LonLat llCenter = Start.getInstance().MapKit().getMapCenter();
//        LonLat llB = new LonLat(llCenter.GetLon() + londegree, llCenter.GetLat());
//        double distance = Start.getInstance().MapKit().getDistance(llCenter, llB);
//
//        LonLat llC = new LonLat(llCenter.GetLon(), llCenter.GetLat() + latdegree);
//        double distance2 = Start.getInstance().MapKit().getDistance(llCenter, llC);

    Point LL2XY(LonLat ll, MapView mapView) {
        Point A = new Point();
        Point B = new Point();
        mapView.getProjection().toProjectedPixels(ll.GetLat(),
                ll.GetLon(), A);
        Projection pj = mapView.getProjection();
        pj.toPixelsFromProjected(A, B);
        return B;
    }

    //在线瓦片图
    public void draw2(Context context, Canvas canvas, MapView mapView) {
        if (!usewg) {
            return;
        }

        if (mapView == null) {
            return;
        }

        int w = mapView.getWidth();
        int h = mapView.getHeight();

        BoundingBox bb = mapView.getBoundingBox();//获取当前区域
        //double[] regions = {_maxLon, _maxLat, _minLon, _minLat};
        double[] regions = {bb.getLonEast(), bb.getLatNorth(), bb.getLonWest(), bb.getLatSouth()};


        float ws = context.getResources().getDisplayMetrics().density;

        double _maxLon, _maxLat, _minLon, _minLat;
        _maxLon = regions[0];
        _maxLat = regions[1];
        _minLon = regions[2];
        _minLat = regions[3];

        IGeoPoint center = mapView.getMapCenter();
        Start.getInstance().MapKit().setMapCenter(center.getLongitude(), center.getLatitude());

        NavFrameSDK.CllDegreePreMeter llDegree = Start.getInstance().MapKit().GetUnitDegree();
        double xLon = llDegree.londegree * wgdistance;//x 轴 单位刻度 0～180
        double xLat = llDegree.latdegree * wgdistance;//y 轴 单位刻度 0～90

        int iX = (int) (_minLon / xLon);
        int eX = (int) (_maxLon / xLon) + 1;
        double x0 = iX * xLon;//网格x0
        double x1 = (iX + 1) * xLon;//网格x1

        int iY = (int) (_minLat / xLat);
        int eY = (int) (_maxLat / xLat) + 1;
        double y0 = iY * xLat;//网格y0
        double y1 = (iY + 1) * xLat;//网格y1

        Point posX0 = LL2XY(new LonLat(x0, y0), mapView);//y0不重要
        Point posX1 = LL2XY(new LonLat(x1, y0), mapView);

        Point posY0 = LL2XY(new LonLat(x0, y0), mapView);//x0不重要
        Point posY1 = LL2XY(new LonLat(x0, y1), mapView);

        int DX = posX1.x - posX0.x;
        int DY = posY0.y - posY1.y;

        if (DX < 50 || DY < 50) {
            return;
        }
//test
//        double dd = Start.getInstance().MapKit().getDistance(new LonLat(x0, y0), new LonLat(x1, y0));

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(2);
        paint.setColor(Color.parseColor("#AAAAAAAA"));
        paint.setAntiAlias(true);

        float startX = 0;
        float startY = 0;
        float stopX = 0;
        float stopY = h;

        for (int i = 0; i < (eX - iX); i++) {
            if (i == 0) {
                startX = posX0.x;
            } else {
                startX += DX;
            }
            canvas.drawLine(startX, startY, startX, stopY, paint);
        }

        startX = w;
        for (int i = 0; i < (eY - iY); i++) {
            if (i == 0) {
                startY = posY1.y;
            } else {
                startY -= DY;
            }
            canvas.drawLine(0, startY, startX, startY, paint);
        }

    }

    //mapforge
    public void draw3(Context context, org.mapsforge.core.graphics.Canvas canvas, org.mapsforge.core.model.BoundingBox bb, byte zoomLevel, org.mapsforge.core.model.Point topLeftPoint, DisplayModel displayModel) {
        if (!usewg) {
            return;
        }

        int w = canvas.getWidth();
        int h = canvas.getHeight();

        double[] regions = {bb.maxLongitude, bb.maxLatitude, bb.minLongitude, bb.minLatitude};

        float ws = context.getResources().getDisplayMetrics().density;

        double _maxLon, _maxLat, _minLon, _minLat;
        _maxLon = regions[0];
        _maxLat = regions[1];
        _minLon = regions[2];
        _minLat = regions[3];

        LatLong center = bb.getCenterPoint();
        Start.getInstance().MapKit().setMapCenter(center.getLongitude(), center.getLatitude());

        NavFrameSDK.CllDegreePreMeter llDegree = Start.getInstance().MapKit().GetUnitDegree();
        double xLon = llDegree.londegree * wgdistance;//x 轴 单位刻度 0～180
        double xLat = llDegree.latdegree * wgdistance;//y 轴 单位刻度 0～90

        int iX = (int) (_minLon / xLon);
        int eX = (int) (_maxLon / xLon) + 1;
        double x0 = iX * xLon;//网格x0
        double x1 = (iX + 1) * xLon;//网格x1

        int iY = (int) (_minLat / xLat);
        int eY = (int) (_maxLat / xLat) + 1;
        double y0 = iY * xLat;//网格y0
        double y1 = (iY + 1) * xLat;//网格y1

        long mapSize = MercatorProjection.getMapSize(zoomLevel, displayModel.getTileSize());
        int x = (int) (MercatorProjection.longitudeToPixelX(x0, mapSize) - topLeftPoint.x);
        int y = (int) (MercatorProjection.latitudeToPixelY(y0, mapSize) - topLeftPoint.y);
        Point posX0 = new Point(x, y);

        x = (int) (MercatorProjection.longitudeToPixelX(x1, mapSize) - topLeftPoint.x);
        y = (int) (MercatorProjection.latitudeToPixelY(y0, mapSize) - topLeftPoint.y);
        Point posX1 = new Point(x, y);

        x = (int) (MercatorProjection.longitudeToPixelX(x0, mapSize) - topLeftPoint.x);
        y = (int) (MercatorProjection.latitudeToPixelY(y0, mapSize) - topLeftPoint.y);
        Point posY0 = new Point(x, y);

        x = (int) (MercatorProjection.longitudeToPixelX(x0, mapSize) - topLeftPoint.x);
        y = (int) (MercatorProjection.latitudeToPixelY(y1, mapSize) - topLeftPoint.y);
        Point posY1 = new Point(x, y);

        int DX = posX1.x - posX0.x;
        int DY = posY0.y - posY1.y;

        if (DX < 50 || DY < 50) {
            return;
        }
//test
//        double dd = Start.getInstance().MapKit().getDistance(new LonLat(x0, y0), new LonLat(x1, y0));

        int startX = 0;
        int startY = 0;
        int stopX = 0;
        int stopY = h;


        org.mapsforge.core.graphics.Paint paint = AndroidGraphicFactory.INSTANCE.createPaint();
        paint.setColor(Color.parseColor("#AAAAAAAA"));
        paint.setStrokeWidth(2);
        paint.setStyle(Style.STROKE);

        for (int i = 0; i < (eX - iX); i++) {
            if (i == 0) {
                startX = posX0.x;
            } else {
                startX += DX;
            }
            canvas.drawLine(startX, startY, startX, stopY, paint);
        }

        startX = w;
        for (int i = 0; i < (eY - iY); i++) {
            if (i == 0) {
                startY = posY1.y;
            } else {
                startY -= DY;
            }
            canvas.drawLine(0, startY, startX, startY, paint);
        }

    }

}
